package com.ai.web.controller;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.ai.web.cache.Constants;
import com.ai.web.http.HttpResponse;
import com.ai.web.http.HttpUtil;
import com.ai.web.service.QrcodeService;
import com.ai.web.util.JsonUtil;
import com.ai.web.util.ZipUtil;
import com.ai.web.vo.QrcodeV;
import com.ai.web.vo.ResultModel;
import com.ai.web.weixin.WeixinContext;

@Controller
@RequestMapping("/qrcode")
public class QrcodeController extends BaseController {

	private static Logger logger = Logger.getLogger(QrcodeController.class);

	@Autowired
	private QrcodeService qrcodeService;

	@RequestMapping(value = "/modal")
	public String modal(Model model) {
		return "qrcode/modal-template";
	}
	
	@RequestMapping(value = "/template")
	public String template(Model model) {
		return "qrcode/qrcode-template";
	}

	@RequestMapping(value = "/get/{serialNumber}")
	@ResponseBody
	public ResultModel getBySerialNumber(
			@PathVariable("serialNumber") String serialNumber,
			HttpServletRequest request) {
		logger.info("-----serialNumber:" + serialNumber);
		ResultModel rm = new ResultModel();
		int maxId = qrcodeService.getMaxId(serialNumber) + 1;
		if (maxId > Constants.MAX_SERIAL_NUMBER) {
			rm.setFailCode();
			rm.setMsg("二维码数量超过最大限制！");
			return rm;
		}
		try {
			String fileSavePath = request.getSession().getServletContext()
					.getRealPath("")
					+ File.separator
					+ "uploadFiles/qrcode/";
			new File(fileSavePath).mkdirs();
			getFile(fileSavePath + serialNumber + ".jpg", serialNumber, maxId, request);
			QrcodeV qrcode = new QrcodeV();
			qrcode.setId(maxId);
			qrcode.setSerialNumber(serialNumber);
			rm = qrcodeService.save(qrcode);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("fileSavePath", fileSavePath);
			map.put("fileName", serialNumber + ".jpg");
			rm.setData(map);
		} catch (Exception e) {
			rm.setFailCode();
			rm.setMsg("微信服务器连接超时，获取二维码图片失败！");
			e.printStackTrace();
		}
		return rm;
	}

	private void getFile(String file, String serialNumber, int maxId,
			HttpServletRequest request) throws Exception {
		String ticket = getTicket(maxId);
		URL url = new URL("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="
				+ ticket);
		logger.info("getFile: https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="
				+ ticket);
		System.setProperty ("jsse.enableSNIExtension", "false");
		InputStream in = url.openStream();
		FileOutputStream fs = new FileOutputStream(file);
		byte[] buf = new byte[1024];
		int r;
		while ((r = in.read(buf)) > 0) {
			fs.write(buf, 0, r);
		}
		in.close();
		fs.close();
		pressText(serialNumber, file, "Helvetica", Font.PLAIN, 12, 25, 375, -5);
	}

	private String getTicket(int maxId) {
		String ticket = "";
		String serviceUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="
				+ WeixinContext.access_token;
		logger.info("qrcode create：" + serviceUrl);
		String body = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": "
				+ maxId + "}}}";
		HttpResponse httpResponse = HttpUtil.httpRequest(serviceUrl, "POST",
				null, body);
		@SuppressWarnings("rawtypes")
		HashMap map = JsonUtil.fromJson(httpResponse.getBody(), HashMap.class);
		Object obj = map.get("errcode");
		if (obj == null) {
			ticket = map.get("ticket").toString();
		} else {
			logger.error("getMenu errcode=" + obj);
		}
		return ticket;
	}

	public static void pressText(String pressText, String targetImg,
			String fontName, int fontStyle, int color, int fontSize, int x,
			int y) {
		try {
			File _file = new File(targetImg);
			Image src = ImageIO.read(_file);
			int wideth = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(wideth, height,
					BufferedImage.TYPE_INT_RGB);
			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, wideth, height, null);
			g.setColor(Color.black);
			g.setFont(new Font(fontName, fontStyle, fontSize));

			float alpha = 0.8f;
			((Graphics2D) g).setComposite(AlphaComposite.getInstance(
					AlphaComposite.SRC_ATOP, alpha));

			g.drawString(pressText, wideth - fontSize - x, height - fontSize
					/ 2 - y);
			g.dispose();
			String formatName = targetImg
					.substring(targetImg.lastIndexOf(".") + 1);
			ImageIO.write(image, formatName, _file);
		} catch (Exception e) {
			e.printStackTrace();
			logger.info(e);
		}
	}

	@ResponseBody
	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	public ResultModel upload(@RequestParam("file") CommonsMultipartFile file,
			String timestamp, HttpServletRequest request)
			throws FileUploadException {
		ResultModel model = new ResultModel();
		String fileName = file.getOriginalFilename();
		String fileSavePath = request.getSession().getServletContext()
				.getRealPath("")
				+ File.separator + "uploadFiles/qrcode/" + new Date().getTime();
		logger.info("------------fileSavePath---------:" + fileSavePath);
		File newFile = new File(fileSavePath);
		newFile.mkdirs();
		newFile = new File(fileSavePath + File.separator + fileName);
		try {
			file.transferTo(newFile);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("fileSavePath", fileSavePath);
			map.put("fileName", fileName);
			model.setData(map);
			model.setSuccessCode();
		} catch (IOException e) {
			e.printStackTrace();
			model.setFailCode();
			model.setMsg("文件上传失败!");
			return model;
		}
		return model;
	}

	@ResponseBody
	@RequestMapping(value = "/get", method = RequestMethod.POST)
	public ResultModel getByFile(@RequestParam String fileSavePath,
			@RequestParam String fileName, HttpServletRequest request) {
		ResultModel model = new ResultModel();
		try {
			InputStreamReader isr = new InputStreamReader(new FileInputStream(
					fileSavePath + File.separator + fileName), "utf-8");
			BufferedReader br = new BufferedReader(isr);
			String serialNumber = null;
			new File(fileSavePath).mkdirs();
			while ((serialNumber = br.readLine()) != null
					&& serialNumber.length() > 0) {
				int maxId = qrcodeService.getMaxId(serialNumber) + 1;
				if (maxId > Constants.MAX_SERIAL_NUMBER) {
					model.setFailCode();
					model.setMsg("二维码数量超过最大限制！");
					return model;
				}
				String tempName = fileSavePath + File.separator + serialNumber + ".jpg";
				getFile(tempName, serialNumber, maxId++, request);
				QrcodeV qrcode = new QrcodeV();
				qrcode.setId(maxId);
				qrcode.setSerialNumber(serialNumber);
				model = qrcodeService.save(qrcode);
			}
			br.close();
			isr.close();
			new File(fileSavePath + File.separator + fileName).delete();
			String relativePath = request.getSession().getServletContext()
					.getRealPath("")
					+ File.separator
					+ "uploadFiles/qrcode/";
			String tempName = new Date().getTime()+".zip";
			ZipUtil.zip(fileSavePath, relativePath + tempName);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("fileSavePath", fileSavePath);
			map.put("fileName", tempName);
			model.setData(map);
			model.setSuccessCode();
		} catch (Exception e) {
			e.printStackTrace();
			model.setFailCode();
			model.setMsg("生成二维码失败！");
			return model;
		}
		return model;
	}
	
	@RequestMapping(value = "/download")
	public void download(@RequestParam String fileName, HttpServletRequest request, HttpServletResponse response) {
		OutputStream os = null;
		try {  
			String relativePath = request.getSession().getServletContext()
					.getRealPath("")
					+ File.separator
					+ "uploadFiles/qrcode/";
			os = response.getOutputStream();  
	    	response.reset();  
	    	String name = new String(fileName.getBytes("GBK"),"ISO8859_1");      
	    	response.addHeader("Content-Disposition", "attachment;filename="+ name);
	    	response.setContentType("application/octet-stream; charset=utf-8");  
	        os.write(FileUtils.readFileToByteArray(new File(relativePath + fileName)));  
	        os.flush();  
	    } catch(Exception e){
	    	e.printStackTrace();
	    	logger.info(e);
	    }finally {  
	        if (os != null) {  
	            try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}  
	        }  
	    }  
	}
}